/**
 * 
 */
package systole.persistence.brokersDB;

import java.util.Date;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.hibernate.criterion.SimpleExpression;
import systole.domain.analysis.Analysis;
import systole.domain.persons.Medic;
import systole.domain.persons.Patient;
import systole.exceptions.ExceptionDAO;
import systole.persistence.FacadeDB;
import systole.persistence.brokersInterface.AnalysisBroker;
import systole.view.messages.ErrorMessages;

/**
 * @author jmj
 * 
 */
public class AnalysisBrokerDB extends BrokerDB implements AnalysisBroker {

    /**
     *
     */
    public AnalysisBrokerDB() {
        super();
    }

    /*
     * (non-Javadoc)
     *
     * @see
     * systole.persistence.brokersInterface.AnalysisBroker#getAnalisysById(long)
     */
    @Override
    public Analysis getAnalisysById(Integer id) throws ExceptionDAO {
        try {            
            this.logger.logDebug("Getting Analysis with id " + id);
            Session currentSession = FacadeDB.getInstance().getCurrentSession();
            Analysis instance = (Analysis) currentSession.get(Analysis.class, id);
            this.logger.logDebug("Anaysis get successfully");
            return instance;
        } catch (HibernateException e) {
            this.logger.logError("error on get analysis, msg: " + e.getMessage());
            throw new ExceptionDAO("No se pudo obtener el Análisis", e.fillInStackTrace());
        }
    }

    /*
     * (non-Javadoc)
     *
     * @see
     * systole.persistence.brokersInterface.AnalysisBroker#getAnalisysByMedic
     * (systole.domain.persons.Medic)
     */
    @Override
    public List<Analysis> getAnalisysByMedic(Medic medic) throws ExceptionDAO {
        try {
            this.logger.logDebug("Getting all Analysis of medic " + medic.toString());
            Session currentSession = FacadeDB.getInstance().getCurrentSession();
            Criteria criteria = currentSession.createCriteria(Analysis.class).add(Restrictions.eq("medic", medic)).addOrder(Order.desc("creationDay"));
            @SuppressWarnings("unchecked")
            List<Analysis> analysis = criteria.list();
            this.logger.logDebug("Anaysis get successfully");
            return analysis;
        } catch (HibernateException e) {
            this.logger.logError("error on get analysis, msg: " + e.getMessage());
            throw new ExceptionDAO("No se pudieron obtener los Análisis", e.fillInStackTrace());
        }
    }

    /*
     * (non-Javadoc)
     *
     * @see
     * systole.persistence.brokersInterface.AnalysisBroker#getAnalisysByPatien
     * (systole.domain.persons.Patient)
     */
    @Override
    public List<Analysis> getAnalisysByPatien(Patient patient) throws ExceptionDAO {
        try {
            this.logger.logDebug("Getting all Analysis of patient " + patient.toString());
            Session currentSession = FacadeDB.getInstance().getCurrentSession();
            Criteria criteria = currentSession.createCriteria(Analysis.class).add(Restrictions.eq("patient", patient)).addOrder(Order.desc("creationDay"));
            @SuppressWarnings("unchecked")
            List<Analysis> analysis = criteria.list();
            this.logger.logDebug("Anaysis get successfully");
            return analysis;
        } catch (HibernateException e) {
            this.logger.logError("error on get analysis, msg: " + e.getMessage());
            throw new ExceptionDAO("No se pudieron obtener los Análisis", e.fillInStackTrace());
        }
    }

    /*
     * (non-Javadoc)
     *
     * @see
     * systole.persistence.brokersInterface.AnalysisBroker#getLastPatientAnalisys
     * (systole.domain.persons.Patient)
     */
    @Override
    public Analysis getLastPatientAnalisys(Patient patient) throws ExceptionDAO {
        try {
            this.logger.logDebug("Getting last Analysis of patient " + patient.toString());
            Session currentSession = FacadeDB.getInstance().getCurrentSession();
            Criteria criteria = currentSession.createCriteria(Analysis.class).add(Restrictions.eq("patient", patient)).addOrder(Order.desc("creationDay")).setMaxResults(1);
            Analysis instance = (Analysis) criteria.uniqueResult();
            if (instance == null) {
                this.logger.logDebug("Analysis not found");
            } else {
                this.logger.logDebug("Analysis found");
            }
            return instance;
        } catch (HibernateException e) {
            this.logger.logError("error on get analysis, msg: " + e.getMessage());
            throw new ExceptionDAO("No se pudo obtener el Análisis", e.fillInStackTrace());
        }
    }

    /*
     * (non-Javadoc)
     *
     * @see
     * systole.persistence.brokersInterface.AnalysisBroker#insert(systole.domain
     * .analysis.Analysis)
     */
    @Override
    public void insert(Analysis analisys) throws ExceptionDAO {
        try {
            this.logger.logDebug("Saving  Analysis");
            Session currentSession = FacadeDB.getInstance().getCurrentSession();
            currentSession.save(analisys);
            this.logger.logDebug("Analysis saved");
        } catch (HibernateException e) {
            this.logger.logError("error on save analysis, msg: " + e.getMessage());
            throw new ExceptionDAO(ErrorMessages.CHANGES_NOT_SAVE, e.fillInStackTrace());
        }
    }

    /*
     * (non-Javadoc)
     *
     * @see
     * systole.persistence.brokersInterface.AnalysisBroker#update(systole.domain
     * .analysis.Analysis)
     */
    @Override
    public void update(Analysis analisys) throws ExceptionDAO {
        try {
            this.logger.logDebug("Updating Analysis");
            Session currentSession = FacadeDB.getInstance().getCurrentSession();
            currentSession.update(analisys);
            this.logger.logDebug("Analysis updated");
        } catch (HibernateException e) {
            this.logger.logError("error on update analysis, msg: " + e.getMessage());
            throw new ExceptionDAO(ErrorMessages.CHANGES_NOT_SAVE, e.fillInStackTrace());
        }
    }

    @Override
    public List<Analysis> getAllAnalisys() throws ExceptionDAO {
        try {
            this.logger.logDebug("Getting all analysis");
            Session currentSession = FacadeDB.getInstance().getCurrentSession();
            @SuppressWarnings("unchecked")
            List<Analysis> list = currentSession.createCriteria(Analysis.class).addOrder(Order.desc("analysisDay")).list();
            this.logger.logDebug("get analysis successfully");
            return list;
        } catch (HibernateException e) {
            this.logger.logError("error on get analysis, msg: " + e.getMessage());
            throw new ExceptionDAO("No se pudieron obtener los análisis", e.fillInStackTrace());
        }
    }

    @SuppressWarnings("unchecked")
	@Override
    public List<Analysis> getAnalysisByDateMedicaPatiente(Date date, Patient patient, Medic medic) throws ExceptionDAO {
        try {
            this.logger.logDebug("Getting analysis by patint, medic and date");
            Session currentSession = FacadeDB.getInstance().getCurrentSession();
            SimpleExpression dateR = (date == null) ? null : Restrictions.eq("analysisDay", date);
            SimpleExpression patientR = (patient == null) ? null : Restrictions.eq("patient", patient);
            SimpleExpression medicR = (medic == null) ? null : Restrictions.eq("medic", medic);

            Criteria criteria = currentSession.createCriteria(Analysis.class);
            if (dateR != null) {
                criteria = criteria.add(dateR);
            }

            if ((patientR != null)) {
                criteria = criteria.add(patientR);
            }

            if (medicR != null) {
                criteria = criteria.add(medicR);
            }
            List<Analysis> list = criteria.list();
            this.logger.logDebug("get analysis successfully");
            return list;
        } catch (HibernateException e) {
            this.logger.logError("error on get analysis by patint, medic and date, msg: " + e.getMessage());
            throw new ExceptionDAO("No se pudieron obtener los análisis", e.fillInStackTrace());
        }
    }
}
